<?php
namespace Home\Logic;
use Lib\Logic\WxcurlLogic;
class WxBusinessAutorizerInfoLogic{
    
    private $wxCurlLogic;
    private $wxBusinessAuthorizerInfoModel;
    private $wxappId;
    
    public function __construct(){
        $this->wxCurlLogic = new WxcurlLogic();
        $this->wxBusinessAuthorizerInfoModel = D('WxBusinessAuthorizerInfo');
        $this->wxappId = C("WX_APPID");
    }
    
    
    /**
     * 获取微信公众号access_token
     * 如果access_token过期，向微信服务器获取最新的access_token
     * @param number $businessUserId
     * @param number $authorizerType
     */
    public function getAccessToken($businessUserId = 0, $authorizerType = 1){
    
        $accessToken = $this->wxBusinessAuthorizerInfoModel->getAccessTokenById($businessUserId);
        if ($accessToken['access_token_expires_time'] <= time()){
            return $this->_refreshToken($businessUserId, $authorizerType);
        } else{
            return $accessToken['authorizer_access_token'];
        }
    }
    
    /**
     * 向微信服务器获取最新的公众号access_token，并更新到数据库
     * 返回最新的access_token
     * @param unknown $businessUserId
     * @param unknown $authorizerType
     */
    private function _refreshToken($businessUserId, $authorizerType){
    
        $refreshData = $this->_getRefreshTokenData($businessUserId, $authorizerType);
    
        if (!$refreshData){
            return false;
        }
    
        $wxComponentLogic = new WxComponentLogic();
    
        $componentAccessToken = $wxComponentLogic->getComponentAccessToken();
    
        if (!$componentAccessToken){
            return false;
        }
    
        //请求微信服务器，并获取最新的access_token
        $this->wxCurlLogic->curlUrl = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=".$componentAccessToken['component_access_token'];
        $this->wxCurlLogic->curlPost = true;
    
        $refreshPostData['component_appid'] = C('WX_APPID');
        $refreshPostData['authorizer_appid'] = $refreshData['authorizer_appid'];
        $refreshPostData['authorizer_refresh_token'] = $refreshData['authorizer_refresh_token'];
    
        $refreshPostData = json_encode($refreshPostData);
    
        $this->wxCurlLogic->curlData = $refreshPostData;
        $refreshToken = $this->wxCurlLogic->wx_curl_exec();
    
        //获取到新的accesstoken插入数据库
        $refreshToken = json_decode($refreshToken, true);
    
        $updateAccessTokenResult = $this->_updateAccessToken($refreshToken, $businessUserId);
        if ($updateAccessTokenResult){
            return $refreshToken['authorizer_access_token'];
        }
    }
    
    
    /**
     * 获取微信公众号access_token刷新令牌
     * @param unknown $businessUserId
     * @param number $authorizerType
     * @return boolean|Ambigous <mixed, NULL, multitype:Ambigous <string, unknown> unknown , multitype:Ambigous <unknown, string> unknown , unknown>
     */
    private function _getRefreshTokenData($businessUserId, $authorizerType = 1){
        if ($businessUserId == 0) {
            return false;
        }
    
        $where['business_user_id'] = $businessUserId;
        //$where['authorizer_type'] = $authorizerType;
    
        $refreshTokenData = $this->wxBusinessAuthorizerInfoModel->field('authorizer_appid,authorizer_refresh_token')->where($where)->find();
    
        return $refreshTokenData;
    
    }
    
    
    /**
     * 更新accessToken到数据库
     * @param unknown $refreshToken
     * @param number $businessId
     */
    private function _updateAccessToken($refreshToken, $businessId = 0){
    
        if ($businessId == 0) {
            return false;
        }
    
        $updateData['authorizer_access_token'] = $refreshToken['authorizer_access_token'];
        $updateData['authorizer_refresh_token'] = $refreshToken['authorizer_refresh_token'];
        $updateData['access_token_expires_time'] = time() + $refreshToken['expires_in'];
    
        $where['business_user_id'] = $businessId;
    
        $result = $this->wxBusinessAuthorizerInfoModel->where($where)->save($updateData);
    
        return $result;
    }
    
    
    /**
     * 使用授权码换取公众号的接口调用凭据和授权信息
     * @param string $authCode
     * @return boolean|Ambigous <boolean, mixed>
     */
    public function getAuthorizerAccessToken($authCode = null, $componentAccessToken = null){
        if (!$authCode){
            return false;
        }
        
        if (!$componentAccessToken){
            return false;
        }
    
        $postData['component_appid'] = $this->wxappId;
        $postData['authorization_code'] = $authCode;
    
        //格式化post数据
        $postData = json_encode($postData);
    
        $wxCurlLogic = new WxcurlLogic();
        $wxCurlLogic->curlUrl = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=".$componentAccessToken;
        $wxCurlLogic->curlPost = true;
        $wxCurlLogic->curlData = $postData;
        $result = $wxCurlLogic->wx_curl_exec();
    
        return $result;
    
    }
    
    /**
     * 更新授权信息到数据库,如果数据库不存在,则插入一条数据.
     * @param unknown $authorizationInfo
     * @param unknown $authCode
     * @param string $businessId
     * @return boolean|unknown
     */
    public function updateAuthorizerData($authorizationInfo, $authCode, $businessId = null){
        
        if ($businessId == null) {
            return false;
        }
        
        $authorizationInfo = json_decode($authorizationInfo, true);
        $authorizationInfo = $authorizationInfo['authorization_info'];
        
        $authorizationInfoData['business_auth_code'] = $authCode;
        $authorizationInfoData['business_user_id'] = session(C('USER_AUTH_KEY'));
        $authorizationInfoData['authorizer_appid'] = $authorizationInfo['authorizer_appid'];
        $authorizationInfoData['authorizer_access_token'] = $authorizationInfo['authorizer_access_token'];
        $authorizationInfoData['authorizer_refresh_token'] = $authorizationInfo['authorizer_refresh_token'];
        $authorizationInfoData['authorizer_func_info'] = json_encode($authorizationInfo['func_info']);
        $authorizationInfoData['access_token_expires_time'] = time() + $authorizationInfo['expires_in'];
        $authorizationInfoData['authorizer_appid'] = $authorizationInfo['authorizer_appid'];
        
        //授权信息记录数据库
        $businessWxAuthorizerInfoModel = M("WxBusinessAuthorizerInfo");
        
        $where['business_user_id'] = $businessId;
        $isExist = $businessWxAuthorizerInfoModel->where($where)->find();
        if ($isExist){
            $authorizationInfoData['update_time'] = time();
            $result = $businessWxAuthorizerInfoModel->where($where)->save($authorizationInfoData);
        } else{
            $authorizationInfoData['create_time'] = time();
            $authorizationInfoData['business_user_id'] = $businessId;
            $result = $businessWxAuthorizerInfoModel->add($authorizationInfoData);
        }
        
        return $result;
    }
    
    /**
     * 获取微信jssdk jsapi_ticket
     * @param string $authorizerAccessToken
     * @param string $businessId
     * @return boolean|mixed|unknown
     */
    public function getJSAPITicket($authorizerAccessToken = null, $businessId = null){
        
        if ($authorizerAccessToken == null){
            return false;
        }
        
        if ($businessId == null){
            return false;
        }
        
        $jsapiTicketWhere['business_user_id'] = $businessId;
        $jsapiTicket = $this->wxBusinessAuthorizerInfoModel->field("jsapi_ticket,jsapi_ticket_expires_time")->where($jsapiTicketWhere)->find();
        
        if (!$jsapiTicket){
            return false;
        }
        
        if ($jsapiTicket['jsapi_ticket_expires_time'] <= time()){
            //微信服务器获取jsapi_ticket
            $jsapiTicketInfo = $this->_getJSAPITicketByWx($authorizerAccessToken);
            $jsapiTicketInfo = json_decode($jsapiTicketInfo, true);
            if ($jsapiTicketInfo['errcode'] == 0){
                //更新ticket到数据库
                $ticketData['jsapi_ticket_expires_time'] = time() + $jsapiTicketInfo['expires_in'];
                $ticketData['jsapi_ticket'] = $jsapiTicketInfo['ticket'];
                $addTicketResult = $this->wxBusinessAuthorizerInfoModel->addTicket($businessId, $ticketData);
                if ($addTicketResult){
                    return $jsapiTicketInfo['ticket'];
                } else{
                    return false;
                }
            } else{
                return false;
            }
        } else{
            //ticket未过期，直接返回数据库中ticket。
            return $jsapiTicket['jsapi_ticket'];
        }
        
    }
    
    private function _getJSAPITicketByWx($authorizerAccessToken){
        $this->wxCurlLogic->curlUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=".$authorizerAccessToken."&type=jsapi";
        $this->wxCurlLogic->curlPost = false;
        $jsapiTicket = $this->wxCurlLogic->wx_curl_exec();
        return $jsapiTicket;
    }
    
    /**
     * 
     * @param unknown $jsapiTicket
     * @param unknown $noncestr
     * @param unknown $timestamp
     * @param unknown $url
     */
    public function sha1JSAPI($jsapiTicket, $noncestr, $timestamp, $url){
        if ($jsapiTicket == null || $noncestr == null || $timestamp == null || $url == null){
            return false;
        }
        
        $str = "jsapi_ticket=".$jsapiTicket."&noncestr=".$noncestr."&timestamp=".$timestamp."&url=".$url;
		$signature = sha1($str);
		return $signature;
    }
    
    
}

?>